package com.dhy.utils;

import  android.content.Context;
import android.net.wifi.WifiManager;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static android.content.Context.WIFI_SERVICE;

public class UDPSendReceive {

    /**
     * 是否停止接收数据
     */
    private boolean isReceive = true;
    /**
     * 实例
     */
    private static UDPSendReceive instance = null;
    /**
     * 异步线程池
     */
    private static final ExecutorService executor = Executors.newCachedThreadPool();
    /**
     * 接发送信息回调函数
     */
    private MesssageCallBack messageCallBack;
    /**
     * UDP指定发送地址
     */
    private InetAddress local = null;
    /**
     * UDP套接字
     */
    public static DatagramSocket udpSocket = null;
    /**
     * Wifi多播锁
     */
    private WifiManager.MulticastLock lock = null;
    /**
     * UDP指定端口号
     */
    private int port = 0;
    private Context context;

    /**
     * 私有化构造函数
     */
    private UDPSendReceive() {
    }

    public static UDPSendReceive getInstance() {
        if (instance == null) {
            instance = new UDPSendReceive();
        }
        return instance;
    }

    public void setContext(Context context){
        this.context = context;
    }

    public void initUdpSocket(final Context context, final int port) {
        this.port = port;
        this.context = context;
        WifiManager manager = (WifiManager) context.getApplicationContext().getSystemService(WIFI_SERVICE);
        
        lock = manager.createMulticastLock("test wifi");
        if (udpSocket == null) {
            try {
                udpSocket = new DatagramSocket(port);
            } catch (SocketException e) {
                e.printStackTrace();
            }
        }
    }

    public void send(final String sendMsg) {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    local = InetAddress.getByName("255.255.255.255");
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                try {
                    if (udpSocket != null && !udpSocket.isClosed()) {
                        //udpSocket.setBroadcast(true);
                        /**
                         * UDP数据包
                         */
                        DatagramPacket udpPacket = null;
                        udpPacket = new DatagramPacket(sendMsg.getBytes(), sendMsg.getBytes().length);
                        udpPacket.setData(sendMsg.getBytes());
                        udpPacket.setLength(sendMsg.getBytes().length);
                        udpPacket.setPort(port);
                        udpPacket.setAddress(local);
                        lock.acquire();
                        udpSocket.send(udpPacket);
                        lock.release();
                        Thread.sleep(500);//当前线程休眠500ms
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public void receive() {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                byte[] data = new byte[1024];
                DatagramPacket udpPacket = null;
                try {
                    udpPacket = new DatagramPacket(data, data.length);
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
                while (true) {
                    try {
                        if (udpSocket.isClosed() || udpSocket == null) {
                            continue;
                        }
                        udpSocket.receive(udpPacket);
                        if (udpPacket.getAddress() != null) {
                            String quest_ip = udpPacket.getAddress().toString().substring(1);
                            String host_ip = NetWorkUtils.getLocalIpAddress(context);

                            if ("255.255.255.255".equals(quest_ip) || host_ip.equals(quest_ip)) {  //不接受广播数据或者自己发出的广播
                                continue;
                            }
                        }
                        if (messageCallBack != null) {
                            messageCallBack.onNewMessageCome(udpPacket);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    /**
     * 接发送消息的回调函数
     * 接收到新消息调用onNewMessageCome()
     */
    public static interface MesssageCallBack {
        void onNewMessageCome(DatagramPacket data);
    }


    public MesssageCallBack getMessageCallBack() {
        return messageCallBack;
    }

    public void setMessageCallBack(MesssageCallBack messageCallBack) {
        this.messageCallBack = messageCallBack;
    }

}
